package com.mp.approvalreq.dao.impl;

import com.mp.approvalreq.dao.GeneralRequestDao;
import com.mp.approvalreq.entity.ConditionFlow;
import com.mp.approvalreq.entity.GeneralRequest.GeneralRequest;
import com.plusmoney.util.SQLLogger;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.math.RoundingMode;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class GeneralRequestDaoImpl extends AbstractDao implements GeneralRequestDao {

	private static final Logger logger = LoggerFactory.getLogger(GeneralRequestDaoImpl.class);

	private Connection connection;

	public GeneralRequestDaoImpl(Connection connection) {
		this.connection = connection;
	}

	private PreparedStatement getPrepareStatement(String sql) throws SQLException {
		return connection.prepareStatement(sql);
	}

	/**
	 * 统一获取方案查询SQL
	 *
	 * @param condition 条件（where……[order by……]/[group by ……] [limit……]）
	 * @return
	 */
	@Override
	String getQuerySql(String condition) {
		final String query = "select Pid, Pcompany_id, Pproject_id, Pspecific_id, Prequest_flow"
				+ " from pt_mp_general_request_flow ";
		return String.format("%s %s", query, condition);
	}


	@Override
	GeneralRequest getObject(ResultSet rs) throws SQLException {
		GeneralRequest generalRequest = new GeneralRequest();
//		generalRequest.setId(rs.getInt(1));
		generalRequest.setGeneralFlowId(rs.getInt(1));
		generalRequest.setCompanyId(rs.getInt(2));
		generalRequest.setProject(rs.getInt(3));
		generalRequest.setSpecificId(rs.getString(4));
		generalRequest.setAllJudger(rs.getString(5));
		return generalRequest;
	}

	@Override
	public List<GeneralRequest> selectAllGeneralRequestFlowByCompanyId(Integer companyId) throws SQLException {
		List<GeneralRequest> list = new ArrayList<>();
		String sql = getQuerySql("where Pcompany_id = ? and Fstate = 0");

		try (PreparedStatement ps = getPrepareStatement(sql)) {
			ps.setInt(1, companyId);
			logger.info(SQLLogger.logSQL(sql, companyId));

			try (ResultSet rs = ps.executeQuery()) {
				while (rs.next()) {
					list.add(getObject(rs));
				}
			}
		}
		return list;
	}

	@Override
	public void updateBatchGeneralRequestFlow(List<GeneralRequest> generalRequests) throws SQLException {
		String sql = "update pt_mp_general_request_flow set Prequest_flow = ?, Fedit_time = now() where Pid = ? and Pcompany_id = ? limit 1";

		try (PreparedStatement ps = getPrepareStatement(sql)) {
			for (GeneralRequest generalRequest : generalRequests) {
				ps.setString(1, generalRequest.getAllJudger());
				ps.setInt(2, generalRequest.getGeneralFlowId());
				ps.setInt(3, generalRequest.getCompanyId());
				logger.info(SQLLogger.logSQL(sql, generalRequest.getAllJudger(), generalRequest.getGeneralFlowId(), generalRequest.getCompanyId()));

				ps.addBatch();
			}

			ps.executeBatch();

		}
	}

	@Override
	public List<GeneralRequest> selectAllGeneralConditionFlowByCompanyId(Integer companyId) throws SQLException {
		List<GeneralRequest> list = new ArrayList<>();
		String sql = "select Fid, Fcompany_id, Frequest_flow"
				+ " from pt_mp_general_request_condition_flow_desc"
				+ " where Fcompany_id = ? and Fstate = 0";

		try (PreparedStatement ps = getPrepareStatement(sql)) {
			ps.setInt(1, companyId);
			logger.info(SQLLogger.logSQL(sql, companyId));

			try (ResultSet rs = ps.executeQuery()) {
				while (rs.next()) {
					GeneralRequest generalRequest = new GeneralRequest();
					generalRequest.setConditionId(rs.getInt(1));
					generalRequest.setCompanyId(rs.getInt(2));
					generalRequest.setAllJudger(rs.getString(3));
					list.add(generalRequest);
				}
			}
			return list;
		}
	}

	@Override
	public void updateBatchGeneralConditionFlow(List<GeneralRequest> conditionFlows) throws SQLException {
		String sql = "update pt_mp_general_request_condition_flow_desc set Frequest_flow = ? where Fid = ? and Fcompany_id = ? limit 1";

		try (PreparedStatement ps = getPrepareStatement(sql)) {
			for (GeneralRequest generalRequest : conditionFlows) {
				ps.setString(1, generalRequest.getAllJudger());
				ps.setInt(2, generalRequest.getConditionId());
				ps.setInt(3, generalRequest.getCompanyId());
				logger.info(SQLLogger.logSQL(sql, generalRequest.getAllJudger(), generalRequest.getConditionId(), generalRequest.getCompanyId()));

				ps.addBatch();
			}

			ps.executeBatch();

		}
	}

	@Override
	public GeneralRequest selectProjectGeneralRequest(Integer companyId, Integer projectId, String specificId) throws SQLException {
		String sql = getQuerySql("where Pcompany_id = ? and Pproject_id = ? and Pspecific_id = ? and Fstate = 0");
		try (PreparedStatement ps = getPrepareStatement(sql)) {
			ps.setInt(1, companyId);
			ps.setInt(2, projectId);
			ps.setString(3, specificId);
			logger.info(SQLLogger.logSQL(sql, companyId, projectId, specificId));
			try (ResultSet rs = ps.executeQuery()) {
				if (rs.next()) {
					return getObject(rs);
				}
			}
		}
		return null;
	}

	@Override
	public GeneralRequest selectProjectDefaultGeneralRequest(Integer companyId, Integer projectId) throws SQLException {
		String sql = getQuerySql("where Pcompany_id = ? and Pproject_id = ? and Fstate = 0");
		try (PreparedStatement ps = getPrepareStatement(sql)) {
			ps.setInt(1, companyId);
			ps.setInt(2, projectId);
			logger.info(SQLLogger.logSQL(sql, companyId, projectId));
			try (ResultSet rs = ps.executeQuery()) {
				if (rs.next()) {
					return getObject(rs);
				}
			}
		}
		return null;
	}

	@Override
	public List<ConditionFlow> selectConditionFlowsById(Integer generalFlowId, Integer companyId) throws SQLException {
		List<ConditionFlow> list = new ArrayList<>();
		String sql = "select Fsmaller_factor,Fgreater_factor,Frequest_flow,Fcondition_calculation_type,Fcondition_type, Frange "
				+ " from approval.pt_mp_general_request_condition_flow_desc"
				+ " where Fgeneral_flow_id = ? and Fcompany_id = ? and Fstate = 0 ";

		try (PreparedStatement ps = getPrepareStatement(sql)) {
			ps.setInt(1, generalFlowId);
			ps.setInt(2, companyId);
			logger.info(SQLLogger.logSQL(sql, generalFlowId, companyId));

			try (ResultSet rs = ps.executeQuery()) {
				while (rs.next()) {
					ConditionFlow conditionFlow = new ConditionFlow();
					conditionFlow.setSmallerFactor(rs.getBigDecimal(1));
					if (conditionFlow.getSmallerFactor() != null) {
						conditionFlow.setSmallerFactor(conditionFlow.getSmallerFactor().setScale(0, RoundingMode.FLOOR));
					}
					conditionFlow.setGreaterFactor(rs.getBigDecimal(2));
					if (conditionFlow.getGreaterFactor() != null) {
						conditionFlow.setGreaterFactor(conditionFlow.getGreaterFactor().setScale(0, RoundingMode.FLOOR));
					}
					conditionFlow.setRequestFlow(rs.getString(3));
					conditionFlow.setConditionCalculationType(rs.getInt(4));
					conditionFlow.setConditionType(rs.getString(5));
					conditionFlow.setRange(rs.getString(6));
					list.add(conditionFlow);
				}
			}
		}
		return list;
	}
}
